package com.whyl.eems.common.oss.ali;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.whyl.eems.common.utils.DateUtils;
import com.whyl.eems.common.oss.ali.ram.StsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

/**
 * 作者：阿坤
 * 创建时间：14:03 2019/8/16
 * 功能描述：阿里云 OSS 工具类
 */
@Component
public class ALiOSSUitls {

    @Autowired
    private StsService stsService;

    //存储节点
    private String endpoint;
    // 存储空间
    private String bucket;
    // 文件夹
    private String folder;


    /**
     * @param inputStream 文件流
     * @param meta        元数据
     * @param fileName    文件名字
     * @param type        文件类型
     * @return url路径
     */
    public String uploadFiles(InputStream inputStream, ObjectMetadata meta, String fileName, String type) {
        AssumeRoleResponse token = stsService.getToken();
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, token.getCredentials().getAccessKeyId(), token.getCredentials().getAccessKeySecret(), token.getCredentials().getSecurityToken());
        try {
            String objectName = folder + "/" + DateUtils.format(new Date()) + "/";
            // 判断 存储空间是否存在
            boolean isObjectExist = ossClient.doesObjectExist(bucket, objectName);
            if (!isObjectExist) {
                ObjectMetadata objectMeta = new ObjectMetadata();
                byte[] buffer = new byte[0];
                ByteArrayInputStream in = new ByteArrayInputStream(buffer);
                objectMeta.setContentLength(0);
                ossClient.putObject(bucket, objectName, in, objectMeta);
                in.close();
            }
            ossClient.putObject(bucket, objectName + fileName + "." + type, inputStream, meta);
            String url = "https://" + bucket + "." + endpoint + "/" + objectName + fileName + "." + type;
            return url;
        } catch (IOException e) {
            e.printStackTrace();
            // 关闭io流
            inputStream.close();
        } finally {
            // 释放资源
            ossClient.shutdown();
            return "";
        }
    }

    /**
     *
     * @param bucketName 存储空间
     * @param url 文件url
     * @return
     */
    public boolean deleteObject(String bucketName, String url) {
        AssumeRoleResponse token = stsService.getToken();
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, token.getCredentials().getAccessKeyId(), token.getCredentials().getAccessKeySecret(), token.getCredentials().getAccessKeySecret());

        String objectName = this.getObjectName(url);
        boolean isOnlyInOSS = ossClient.doesObjectExist(bucketName, objectName);
        System.out.println("文件是否存在:" + isOnlyInOSS);

        // 删除文件
        if (isOnlyInOSS) {
            ossClient.deleteObject(bucketName, objectName);
            return true;
        }
        // 释放资源
        ossClient.shutdown();
        return false;
    }

    public String getObjectName(String url) {
        if (url == null || "".equals(url)) {
            return "";
        }
        return url.substring(url.indexOf(folder), url.length());
    }

    // 设置元数据
    public ObjectMetadata getObjectMetadata(String fileMD5, String contentType, int contentLength, Date expirationTime, String contentEncoding, String header, String headerValue) {
        ObjectMetadata meta = new ObjectMetadata();
        // 开启文件内容MD5校验。开启后OSS会把您提供的MD5与文件的MD5比较，不一致则抛出异常。
        meta.setContentMD5(fileMD5);
        // 指定上传的内容类型。内容类型决定浏览器将以什么形式、什么编码读取文件。如果没有指定则根据文件的扩展名生成，如果没有扩展名则为默认值application/octet-stream。
        meta.setContentType(contentType);
        // 设置内容被下载时的名称。
//        meta.setContentDisposition("attachment; filename=\"DownloadFilename\"");
        // 设置上传文件的长度。如超过此长度，则会被截断，为设置的长度。如不足，则为上传文件的实际长度。
        meta.setContentLength(contentLength);
        // 设置内容被下载时网页的缓存行为。
        meta.setCacheControl("Download Action");
        // 设置缓存过期时间，格式是格林威治时间（GMT）。
        meta.setExpirationTime(expirationTime);
        // 设置内容被下载时的编码格式。
        meta.setContentEncoding("utf-8");
        // 设置header。
        meta.setHeader(header, headerValue);
        return meta;
    }

    public String getBucket() {
        return bucket;
    }

    public void setBucket(String bucket) {
        this.bucket = bucket;
    }

    public String getFolder() {
        return folder;
    }

    public void setFolder(String folder) {
        this.folder = folder;
    }

    public String getEndpoint() {
        return endpoint;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }
}
